/*

Morpheme
Copyright (C) 2012 Francisco Monteiro

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

http://code.google.com/p/morpheme-tumblr-theme/

*/

var MyExtension = {
	load: function(configs) {
		'use strict';

		$.extend(MyExtension.config, configs);

		//--- <SHARED CONFIGS>
		MyExtension.morphemeConfig.postsPerLoad = configs.postsPerLoad;
		//--- </SHARED CONFIGS>



if (MyExtension.config.debug) {
	var
		plusone = 'http:\/\/apis.google.com\/js\/plusone.js',
		loadScript = true,
		scripts = document.getElementsByTagName('script');
	for (var i = 0; i < scripts.length; i++) {
		if (scripts[i].src === plusone) {
			loadScript = false;
			break;
		}
	}

	if (loadScript) {
		Morpheme.utils.script.load(
			null,
			2000,
			plusone
		);
	}
}



		if (
			MyExtension.config.suggestions &&
			(MyExtension.morphemeConfig.url === window.location.href)
		) {
			var suggestions = document.getElementById(MyExtension.config.suggestions);
			suggestions.style.visibility = 'visible';
			suggestions.style.display = 'inline-block';

			MyExtension.utils.button.setButtonState(false, false, false, false);
		} else {
			Morpheme.initialize(MyExtension.morphemeConfig);

			MyExtension.utils.button.setButtonState(Morpheme.loadPosts(), false, false, true);
		}

		if (MyExtension.config.spanPopup) {
			var
				commonCSS = (
					//(navigator.appName === 'Microsoft Internet Explorer')
					//	? 
						'background-color: lightgray; padding: 2px;'
					//	: 'text-shadow: -1px -1px #a0a0a0, 1px 1px #a0a0a0;'
				) + 'opacity: 0.6;' + ((navigator.appName === 'Microsoft Internet Explorer') ? 'filter: alpha(opacity=60);' : ''),
				sideCSS = commonCSS + 'color: blue;',
				centerCSS = commonCSS + 'color: red;';
			commonCSS += 'color: black;';

			var spanPopup = document.getElementById(MyExtension.config.spanPopup);
			spanPopup.innerHTML = 
				'<div id="divPopupMorpheme" class="overlayMorpheme">' +
					'<table ' +
						'id="tablePopupMorpheme" ' +
						'border="0" cellspacing="0" cellpadding="0" ' +
						'style="width: 100%; height: 100%;">' +
						'<tr>' +
							(
								function(args) {
									var
										output = '',
										aux = function(position) {
											switch (position) {
												case -1: return 'MyExtension.utils.cursor(false)';
												case  0: return 'MyExtension.utils.fullScreen(false)';
												case  1: return 'MyExtension.utils.cursor(true)';
											}
										};

									for (var i = 0; i < args.length; i++) {
										output +=
											'<td ' +
												((args[i].position === 0) ? '' : 'rowspan="2" ') +
												'onclick="javascript:' +
													aux(args[i].position) +
													'; return false;" ' +
												'style="width: ' + ((args[i].position === 0) ? '4' : '3') + '0%; text-align: center; vertical-align: middle;">' +
												'<span id="span' + args[i].name + 'Morpheme">' +
													'<h3>' +
														'<span style="' + ((args[i].position === 0) ? centerCSS : sideCSS) + '">click <\/span><span style="' + commonCSS + '">' + args[i].description + '<\/span><br \/>' +
														'<br \/>' +
														'<span style="' + commonCSS + '">or press <\/span><span style="' + ((args[i].position === 0) ? centerCSS : sideCSS) + '">' + args[i].key + '<\/span><br \/>' +
														'<br \/>' +
														'<span style="' + commonCSS + '">' + ((args[i].position === 0) ? 'to' : 'for') + '<\/span>' +
													'<\/h3><br \/>' +
													'<br \/>' +
													'<h2><span style="' + ((args[i].position === 0) ? centerCSS : sideCSS) + '">' + args[i].name.toUpperCase() + '<\/span><\/h2><br \/>' +
													'<br \/>' +
													'<h3><span style="' + commonCSS + '">' + ((args[i].position === 0) ? 'fullscreen' : 'photo') + '<\/span><\/h3>' +
												'<\/span>' +
											'<\/td>';
									}
									return output;
								}
							)([
								{ position: -1, name: 'Previous', description: 'Left Side',  key: 'P'   },
								{ position:  0, name: 'Exit',     description: 'Center',     key: 'Esc' },
								{ position:  1, name: 'Next',     description: 'Right Side', key: 'N'   }
							]) +
						'<\/tr>' +
						'<tr>' +
							'<td ' +
								'style="height: 40px; text-align: center; vertical-align: top;" ' +
								'onclick="javascript: MyExtension.utils.popupImage(true); return false;">' +
								'<span id="spanMessageMorpheme" style="' + commonCSS + '"><\/span>&nbsp;' +
							'<\/td>' +
						'<\/tr>' +
					'<\/table>' +
				'<\/div>';



		}
		if (MyExtension.config.spanMenu) {
			var buildShortcutList = function(args) {
				var output = '';
				for (var i = 0; i < args.length; i++) {
					if (args[i].skip) { continue; }

					output += '<tr>' +
						'<td style="vertical-align: top;"><b>' + args[i].key + '<\/b><\/td>' +
						'<td style="vertical-align: top;">&nbsp;-&nbsp;<\/td>' +
						'<td style="vertical-align: top; width: 100%">' + args[i].description + '<\/td>' +
					'<\/tr>';
				}
				return output;
			};

			var spanMenu = document.getElementById(MyExtension.config.spanMenu);
			spanMenu.innerHTML = 
				'<ul ' +


// ToDos: here!
'class="DDMenu" ' +


					'id="' + MyExtension.config.divShortcuts + '">' +
					'<li>' +
						'<span>Shortcuts<\/span>' +
						'<ul>' +
							'<li>' +
								'Keyboard Shortcuts<hr \/>' +
								'<table border="0" cellspacing="0" cellpadding="0">' +
									buildShortcutList([
										{ key: 'N/J', description: 'Next post', skip: false },
										{ key: 'P/K', description: 'Previous post', skip: false },
										{ key: 'O', description: 'Open post', skip: false },
										{ key: 'R', description: 'Reblog post', skip: false },
										{ key: 'L', description: 'Like?', skip: !(typeof Tumblr === 'undefined') },
										{ key: 'G', description: 'Search image at Google Image', skip: !(MyExtension.config.inline ? MyExtension.config.showGoogleImageSearchInline : MyExtension.config.showGoogleImageSearch) },
										{ key: 'T', description: 'Search image at TinEye', skip: !(MyExtension.config.inline ? MyExtension.config.showTinEyeImageSearchInline : MyExtension.config.showTinEyeImageSearch) },
										{ key: 'S', description: 'View Source (if available)', skip: false },
										{ key: 'F', description: 'enter fullscreen mode (photo posts only,<br \/>on Touchscreen devices click the photo on post)', skip: false }
									]) +
								'<\/table>' +
								'<br \/>' +
								'additionally in Fullscreen mode:' +
								'<table border="0" cellspacing="0" cellpadding="0">' +
									buildShortcutList([
										{ key: 'Esc', description: 'Exit fullscreen mode (on Touchscreen<br \/>devices click center to exit)', skip: false },
										{ key: 'PgDown', description: 'Next post (on Touchscreen<br \/>devices click right side for next)', skip: false },
										{ key: 'PgUp', description: 'Previous post (on Touchscreen<br \/>devices click left side for previous)', skip: false }
									]) +
								'<\/table>' +
							'<\/li>' +
						'<\/ul>' +
					'<\/li>' +
				'<\/ul>';

		}

	},

	config: { // ___________________________________________________ default config:
		inline: false,
		showAvatar: true,

		showDate: true,
		showDateInline: false,
		showGoogleImageSearch: true,
		showGoogleImageSearchInline: true,
		showTinEyeImageSearch: true,
		showTinEyeImageSearchInline: true,
		showViewHRImage: true,
		showViewHRImageInline: false,
		showSource: true,
		showSourceInline: true,
		showTags: true,
		showTagsInline: true,
		showTagSearchGoogle: true,
		showTagSearchTumblrGoogle: true,
		showTagSearchTumblr: true,
		skipTagSearchFor: 'unknown|about|faq|ask|photo|video|music',
		showPostType: true,
		showPostTypeInline: true,
		showPostTypeFilter: false,

		blockScripts: true,
		showPlayers: false,


// ToDos: here!
divShortcuts: 'divShortcutsMorpheme',


		//--- <SHARED CONFIGS>
		postsPerLoad: 16, // this should match the posts per page you've configured for your tumblr (only if you're running this as a tumblr theme)
		//--- </SHARED CONFIGS>

		debug: (Morpheme.utils.url.getParam.byName('debug') === 'true'),
		showEdit: false // doesn't make much sence for public (like on a tumblr theme), very usefull if local or private
	},

	morphemeConfig: {
		// NON optional configs
		//url: 'http://www.google.com',
		url: (Morpheme.utils.url.getParam.byName('url') ? decodeURIComponent(Morpheme.utils.url.getParam.byName('url')) : window.location.href),

		// optional configs
		startPage: 0,
		postsPerLoad: 16, // this should match the posts per page you've configured for your tumblr (only if you're running this as a tumblr theme)
		postType: Morpheme.utils.url.getParam.byName('type'),
		timeout: 10000,

		morphemeExtensionEvents: {
			initialize: function() {
				'use strict';


				//if (Morpheme.state.postId) {
				//	MyExtension.utils.button.hide();
				//}


				// MyExtension.config.inline
				if (Morpheme.utils.url.getParam.byName('inline')) {
					MyExtension.config.inline = (Morpheme.utils.url.getParam.byName('inline') === 'true');
				}
				if (MyExtension.config.inline && Morpheme.state.postId) {
					MyExtension.config.inline = false;
				}


				MyExtension.state.photoRes = MyExtension.config.inline ? 250 : 500; //1280//500//400//250//100//75
				MyExtension.state.photosRes = MyExtension.config.inline ? 75 : 100; //1280//500//400//250//100//75


				// Events: scroll
				$(window).scroll(function (event) {
					//'use strict'; // Unnecessary directive "use strict".

					//if (MyExtension.state.fullscreen) { event.preventDefault(); return; }

if (MyExtension.state.fullscreen) {
	// ToDos: here! need a better solution for touch screen devices
	MyExtension.utils.divPopup().style.top = $(window).scrollTop() + 'px';
}


					if (MyExtension.utils.tumblr_controls()) {
						MyExtension.utils.tumblr_controls().style.position = 'absolute';
						MyExtension.utils.tumblr_controls().style.top = ($(window).scrollTop()) + 'px';
						MyExtension.utils.tumblr_controls().style.right = '0px';
					}
					MyExtension.utils.divShortcuts().style.top = ($(window).scrollTop() + 30) + 'px';

					if (Morpheme.state.isRunning || Morpheme.state.finished) {
						return;
					} else if (
						Math.round(
							$(document).height() - ($(window).scrollTop() + $(window).height())
						) <= 1 // doesn't always work with 0
					) {
						if (Morpheme.loadPosts()) { MyExtension.utils.button.setButtonState(false, false, false, true); }
					}
				});

				// Events: keydown
				var keyEvent = function(event) {
					//'use strict'; // Unnecessary directive "use strict".

					//event.preventDefault();

					var isNext = false;
					switch (event.which) {

						case 78:  // [N]
						case 110:
                 case 74:
                 case 106:
							isNext = true;

							// let if fall!

						case 80:  // [P]
						case 112:
                 case 75:
                 case 107:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.cursor(isNext); }
							break;

						case 33: // PgUp
							if (!event.ctrlKey && !event.altKey) {
								if (
									MyExtension.state.fullscreen 

									// ToDos: here!
									//|| !MyExtension.config.inline
								) {
									event.preventDefault();

									MyExtension.utils.cursor(false);
								}
								//else {
								//	// ToDos: here!

								//	//event.preventDefault();
								//	//MyExtension.utils.Page(false);
								//}
							}
							break;
						case 34: // PgDown
							if (!event.ctrlKey && !event.altKey) {
								if (
									MyExtension.state.fullscreen

									// ToDos: here!
									//|| !MyExtension.config.inline
								) {
									event.preventDefault();

									MyExtension.utils.cursor(true);
								}
								//else {
								//	// ToDos: here!

								//	//event.preventDefault();
								//	//MyExtension.utils.Page(true);
								//}
							}
							break;

						case 70: // [F]
						case 102:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.fullScreen(true); }
							break;
						
						case 27: // esc
							MyExtension.utils.fullScreen(false);
							break;

						case 82:  // [R]
						case 114:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.anchorOpen('reblogMorpheme', Morpheme.state.postId, false); }
							break;
						case 69:  // [E]
						case 101:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.anchorOpen('editMorpheme', Morpheme.state.postId, false); }
							break;
						case 79:  // [O]
						case 111:
						case 86:  // [V]
						case 118:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.anchorOpen('viewMorpheme', !event.shiftKey, true); }
							break;
						case 83:  // [S]
						case 115:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.anchorOpen('sourceMorpheme', !event.shiftKey, false); }
							break;
						case 71:  // [G]
						case 103:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.anchorOpen('googleMorpheme', false, false); }
							break;
						case 72:  // [H]
						case 104:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.anchorOpen('highresMorpheme', false, false); }
							break;
						case 84:  // [T]
						case 116:
							if (!event.ctrlKey && !event.altKey) { MyExtension.utils.anchorOpen('tineyeMorpheme', false, false); }
							break;

						case 76:  // [L]
						case 108:
							if (
								!event.ctrlKey &&
								!event.altKey &&
								MyExtension.state.cursorPosition &&
								(typeof Tumblr === 'undefined')
							) {
								var anchors = MyExtension.state.cursorPosition.getElementsByTagName('a');
								for (var i = 0; i < anchors.length; i++) {
									if (anchors[i].id === 'likeMorpheme') {
										eval(

											// this onclick event will return something, to stop it from returning here,
											// I encapsulated it's code in a function

											'function doclickMorpheme() {' +
												anchors[i].getAttribute('onclick') +
											'}' +
											'doclickMorpheme();'
										);
										break;
									}
								}
							}
							break;

						//case 16: // shift
						//case 17: // ctrl
						//case 18: // alt
						//case 9:  // tab
						//	break;
						default:
							//if (MyExtension.config.debug) {
							//	alert(
							//		'which: ' + event.which + '\n' +
							//		'ctrlKey: ' + event.ctrlKey + '\n' +
							//		'shiftKey: ' + event.shiftKey + '\n' +
							//		'altKey: ' + event.altKey + '\n' +
							//		'which char: ' + String.fromCharCode(event.which)
							//	);
							//}
							break;
					}
				};
				$(window).keydown(keyEvent);
				//MyExtension.utils.body().onkeydown = keyEvent;

			},
			headReady: function() {
				'use strict';

				if (MyExtension.config.linkAvatar) {
					$('#' + MyExtension.config.linkAvatar).prop('href', Morpheme.utils.tumblrAPI.avatar(null, 0));
				}

				if (MyExtension.config.pageTitle) {
					document.getElementById(MyExtension.config.pageTitle).innerHTML =
						tumblr_api_read.tumblelog.title +
						(MyExtension.utils.isViewer()
							? '&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;\/|\/|orpheme'
							: ''
						)
					;
				}

				var
					doc = document,
					anchorHome = (MyExtension.config.debug ? Morpheme.state.json : Morpheme.state.blogUrl),
					tableCellAvatar1 = doc.getElementById(MyExtension.config.tableCellAvatar1),
					tableCellAvatar2 = doc.getElementById(MyExtension.config.tableCellAvatar2);
				if (MyExtension.config.showAvatar) {
					doc.getElementById(MyExtension.config.imageAvatar).src = Morpheme.utils.tumblrAPI.avatar(null, null);

					doc.getElementById(MyExtension.config.anchorHome1).href = anchorHome;
				} else {
					if (tableCellAvatar1) {
						tableCellAvatar1.style.visibility = 'hidden';
						tableCellAvatar1.style.display = 'none';
					}

					if (tableCellAvatar2) {
						tableCellAvatar2.style.visibility = 'hidden';
						tableCellAvatar2.style.display = 'none';
					}
				}

				doc.getElementById(MyExtension.config.headerTitle).innerHTML 
					= (
						(MyExtension.config.blockScripts && !MyExtension.utils.isViewer())
							? Morpheme.utils.stripper.stripScripts(tumblr_api_read.tumblelog.title)
							: tumblr_api_read.tumblelog.title
					);
				doc.getElementById(MyExtension.config.tableCellDescription).innerHTML 
					= (
						(MyExtension.config.blockScripts && !MyExtension.utils.isViewer())
							? Morpheme.utils.stripper.stripScripts(tumblr_api_read.tumblelog.description)
							: tumblr_api_read.tumblelog.description
					);

				doc.getElementById(MyExtension.config.anchorHome2).href = anchorHome;
			},
			postsReady: function(finished) {
				'use strict';

				MyExtension.state.isRunning = true;

				var htmlCode = '<span id="spanPage' + Morpheme.state.currentPage + '" class="PostPageMorpheme">';
				if (MyExtension.config.debug) {
					htmlCode += 
						'<span ' +
							'class="postMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' + 
							'page:' + Morpheme.state.currentPage + 
						'<\/span>' + 
						MyExtension.utils.conditionalBreakLine(MyExtension.state.postCount)
					;

					MyExtension.state.postCount++;
				}
				for (var i = 0; i < tumblr_api_read.posts.length; i++) {
					var htmlTagsCode = '';
					if (MyExtension.config.inline ? MyExtension.config.showTagsInline : MyExtension.config.showTags) {
						var tags = tumblr_api_read.posts[i].tags;
						if (tags) {
							for (var j = 0; j < tags.length; j++) {

								var
									skip = false,
									skipTags = MyExtension.config.skipTagSearchFor.split('|');
								for (var k = 0; k < skipTags.length; k++) {
									if (skipTags[k].toLowerCase() === tags[j].toLowerCase()) {
										skip = true;
										break;
									}
								}

								var htmltagcode = '#&nbsp;<a ' +
									//'class="buttonMorpheme smallMorpheme" ' +
									//(MyExtension.utils.isViewer()
									//	? ''
									//	: 'target="_blank" '
									//)  +
									'title="Search for ' + tags[j] + ' at ' + tumblr_api_read.tumblelog.name + '" ' +
									'href="' +
										MyExtension.utils.urlConvertToInternal(
											tumblr_api_read.tumblelog.cname ?
												('http:\/\/' + tumblr_api_read.tumblelog.cname + '\/tagged\/' + tags[j]) // .replace(/ /gi, '_')
												: ('http:\/\/' + tumblr_api_read.tumblelog.name + '.tumblr.com\/tagged\/' + tags[j]) // .replace(/ /gi, '_')
										) +
									'">' + tags[j] + '<\/a>&nbsp; '
								;

								if (!skip) {
									if (MyExtension.config.showTagSearchGoogle)       { htmltagcode += '<a class="buttonMorpheme smallMorpheme" target="_blank" title="Search for ' + tags[j] + ' at Google"                  href="https:\/\/www.google.com\/search?newwindow=1&tbm=isch&q=%22'                 + tags[j].replace(/ /gi, '+') + '%22">' + (MyExtension.config.inline ? 'G' :  'Google')        + '<\/a>&nbsp;'; }
									if (MyExtension.config.showTagSearchTumblrGoogle) { htmltagcode += '<a class="buttonMorpheme smallMorpheme" target="_blank" title="Search for ' + tags[j] + ' on other Tumblrs at Google" href="https:\/\/www.google.com\/search?newwindow=1&tbm=isch&q=site:tumblr.com+%22' + tags[j].replace(/ /gi, '+') + '%22">' + (MyExtension.config.inline ? 'GT' : 'Google Tumblr') + '<\/a>&nbsp;'; }
									if (MyExtension.config.showTagSearchTumblr)       { htmltagcode += '<a class="buttonMorpheme smallMorpheme" target="_blank" title="Search for ' + tags[j] + ' on other Tumblrs at Tumblr" href="https:\/\/www.tumblr.com\/tagged\/'                                          + tags[j].replace(/ /gi, '+') +    '">' + (MyExtension.config.inline ? 'T' :  'Tumblr')        + '<\/a>&nbsp;'; }
								}
								
								htmltagcode += '<br \/>';

								if (skip) { // skiped tags fall to end
									htmlTagsCode += htmltagcode;
								} else {
									htmlTagsCode = htmltagcode + htmlTagsCode;
								}
							}
							//htmlTagsCode += '<br \/>';
						}
					}

					var htmlPhotosCode = '';
					if ((tumblr_api_read.posts[i].type === 'photo') && (tumblr_api_read.posts[i].photos.length > 0)) {
						var photos = tumblr_api_read.posts[i].photos;

						// note: the first photo is the same as the photo post main photo, hence it is ignored here with j starting at 1
						for (var m = 1; m < photos.length; m++) {
							if (htmlPhotosCode === '') {
								htmlPhotosCode += '<br \/><br \/>';
							}
							htmlPhotosCode += '<a ' + (MyExtension.utils.isViewer() ? '' : 'target="_blank" ') + 
							(MyExtension.utils.isViewer() ? (
								'onclick="javascript:' +
									'MyExtension.utils.moveCursorPosition(\'spanPostMorpheme' + tumblr_api_read.posts[i].id + '\');' +
									'MyExtension.utils.fullScreen(true);' +
									'return false;" '
							) : '') +
							'href="' + (
								Morpheme.state.postId 
									? photos[m]['photo-url-1280']
									: MyExtension.utils.urlConvertToInternal(tumblr_api_read.posts[i].url)
							) + '"><img src="' + photos[m]['photo-url-' + MyExtension.state.photosRes] + '" \/><\/a> ';
						}
					}

					var htmlConversationCode = '';
					if ((tumblr_api_read.posts[i].type === 'conversation') && (tumblr_api_read.posts[i].conversation.length > 0)) {
						for (
							var
								conversation = tumblr_api_read.posts[i].conversation,
								l = 0;
							l < conversation.length;
							l++
						) {
							htmlConversationCode +=
								'<b>' + (MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(conversation[l].name) : conversation[l].name) + '<\/b>: ' +
								(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(conversation[l].phrase) : conversation[l].phrase) + '<br \/>'
							;
						}
					}

					var htmlSourceCode = null;
					if (MyExtension.config.inline ? MyExtension.config.showSourceInline : MyExtension.config.showSource) {
						switch (tumblr_api_read.posts[i].type) {
							case 'photo':
								htmlSourceCode = tumblr_api_read.posts[i]['photo-link-url'];
								break;
							case 'video':
								if (
// ToDos: here! refactor this, it looks bad, must check if it is an URL, tumblr sends iframes and objects here and these are not supported here

									(tumblr_api_read.posts[i]['video-source'] != null) &&

									(tumblr_api_read.posts[i]['video-source'].toLowerCase().indexOf('http') === 0) &&
									(tumblr_api_read.posts[i]['video-source'].indexOf('\'') < 0) &&
									(tumblr_api_read.posts[i]['video-source'].indexOf('<') < 0) &&
									(tumblr_api_read.posts[i]['video-source'].indexOf('>') < 0)
								) {
									htmlSourceCode = tumblr_api_read.posts[i]['video-source'];
								}
								break;
							case 'link':
								htmlSourceCode = tumblr_api_read.posts[i]['link-url'];
								break;
						}
					}

					var htmlHeadPhotoCode = (
						(tumblr_api_read.posts[i].type === 'photo')
							? (
								// High Res
								((MyExtension.config.inline ? MyExtension.config.showViewHRImageInline : MyExtension.config.showViewHRImage)
									? '<a id="highresMorpheme" class="buttonMorpheme smallMorpheme" title="[H] View Image in High Resolution" target="_blank"  href="' + tumblr_api_read.posts[i]['photo-url-1280'] + '">'                                                                 + (MyExtension.config.inline ? 'Hi' : 'High Res')      + '<\/a>'
									: ''
								) +
								// Search Google Images
								((MyExtension.config.inline ? MyExtension.config.showGoogleImageSearchInline : MyExtension.config.showGoogleImageSearch)
									? '<a id="googleMorpheme" class="buttonMorpheme smallMorpheme" target="_blank" title="[G] - Search image at Google Images" href="http:\/\/google.com\/searchbyimage?image_url=' + encodeURIComponent(tumblr_api_read.posts[i]['photo-url-500']) + '">' + (MyExtension.config.inline ? 'GI' : 'Google Images') + '<\/a>'
									: ''
								) +
								// Search TinEye
								((MyExtension.config.inline ? MyExtension.config.showTinEyeImageSearchInline : MyExtension.config.showTinEyeImageSearch)
									? '<a id="tineyeMorpheme" class="buttonMorpheme smallMorpheme" target="_blank" title="[T] - Search image at TinEye"        href="http:\/\/www.tineye.com\/search\/?url='        + encodeURIComponent(tumblr_api_read.posts[i]['photo-url-500']) + '">' + (MyExtension.config.inline ? 'TE' : 'TinEye' )       + '<\/a>'
									: ''
								)
							)
							: ''
					);

					var htmlHeadCode =
						'<a id="viewMorpheme" class="buttonMorpheme smallMorpheme" title="[O] - Open Post" ' +

						//(MyExtension.utils.isViewer() ? '' : 'target="_blank" ') +
						'href="' +
							MyExtension.utils.urlConvertToInternal(
								tumblr_api_read.posts[i].url
							) +
						'">' + (MyExtension.config.inline ? 'O' : 'Open') + '<\/a>' + // '&infin;'
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
((typeof Tumblr === 'undefined')
	? (
						'<a id="likeMorpheme" class="buttonMorpheme smallMorpheme" title="[L] - Like?" onclick="javascript:' +
							'var tumblr_control = document.getElementById(\'tumblr_controls' + tumblr_api_read.posts[i].id + '\');' +
							'tumblr_control.src=\'' + Morpheme.utils.tumblrAPI.likeIFrame(i, Morpheme.state.blogUrl) + '\';' +

							(MyExtension.config.debug
								? (
									'var facebook_control = document.getElementById(\'facebook_controls' + tumblr_api_read.posts[i].id + '\');' +
									'facebook_control.src=\'http:\/\/www.facebook.com\/plugins\/like.php?href=' + encodeURIComponent(tumblr_api_read.posts[i].url) + '&layout=button_count&show_faces=false&width=80&action=like&font=lucida+grande&colorscheme=light\';' +

'if (gapi) { gapi.plusone.render(\'googleplus_controls' + tumblr_api_read.posts[i].id + '\'); }'

								)
								: ''
							) +

							'var tableLikesMorpheme = document.getElementById(\'tableLikesMorpheme' + tumblr_api_read.posts[i].id + '\');' +
							'tableLikesMorpheme.style.visibility = \'visible\';' +
							'tableLikesMorpheme.style.display = \'block\';' +

							//'if (this) { this.style.visibility = \'hidden\'; }' +
							'return false;">' + (MyExtension.config.inline ? 'L' : 'Like?') + '<\/a>' 
	) 
	: ''
) + 
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
((typeof Tumblr === 'undefined')
	? (
						'<a id="reblogMorpheme" class="buttonMorpheme smallMorpheme" title="[R] - Reblog" target="_blank" href="' +
							'http:\/\/www.tumblr.com\/reblog\/' + tumblr_api_read.posts[i].id + '\/' + tumblr_api_read.posts[i]['reblog-key'] +
							'?redirect_to=' + encodeURIComponent(tumblr_api_read.posts[i].url) +
						'">' + (MyExtension.config.inline ? 'R' : 'Reblog') + '<\/a>'
	)
	: ''
) +
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
						(htmlSourceCode
							? '<a id="sourceMorpheme" class="buttonMorpheme smallMorpheme" title="[S] - View Source" target="_blank" href="' + htmlSourceCode + '">' + (MyExtension.config.inline ? 'S' : 'Source') + '<\/a>'
							: ''
						) +
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
						(MyExtension.config.showEdit
							? (
								'<a id="editMorpheme" class="buttonMorpheme smallMorpheme" title="[E] - Edit" target="_blank" ' +
									'href="http:\/\/www.tumblr.com\/edit\/' + tumblr_api_read.posts[i].id +
									'?redirect_to=' + encodeURIComponent(tumblr_api_read.posts[i].url) +
									'">' + (MyExtension.config.inline ? 'E' : 'Edit') + '<\/a>'
							)
							: ''
						) +
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
						htmlHeadPhotoCode +
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
						((MyExtension.config.inline ? MyExtension.config.showDateInline : MyExtension.config.showDate)
							? (
								'<span class="headTextMorpheme">' + tumblr_api_read.posts[i]['date-gmt'].substring(0, 16) + '<\/span>'
							)
							: ''
						) +
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
						((MyExtension.config.inline ? MyExtension.config.showPostTypeInline : MyExtension.config.showPostType)
							? (
								'<span' +
									(MyExtension.config.showPostTypeFilter
										? (
											'>' +
												'<a ' +
													'title="filter ' + tumblr_api_read.posts[i].type + ' posts only" ' +
													'class="buttonMorpheme smallMorpheme" ' +
													'href="' +
														MyExtension.utils.buildQuery(
															MyExtension.config.inline,
															tumblr_api_read.posts[i].type,
															MyExtension.utils.isViewer()
														) +
													'">' +
													tumblr_api_read.posts[i].type +
												'<\/a>'
										)
										: (
											' class="headTextMorpheme">' +
												'[&nbsp;' + tumblr_api_read.posts[i].type + '&nbsp;]'
										)
									) +
								'<\/span>'
							)
							: ''
						) +
						///////////////////////////////////////////////////////////////////////////////////////////////////////////
((typeof Tumblr === 'undefined')
	? ''
	: (
						'<span style="float: right; clear: both;">' +
						'<span ' +
							'title="Like" ' +
							'class="like_button" ' +
							'data-post-id="' + tumblr_api_read.posts[i].id + '" ' +
							'id="like_button_' + tumblr_api_read.posts[i].id + '">' +
							'<iframe ' +
								'title="Like" ' +
								'id="like_iframe_' + tumblr_api_read.posts[i].id + '" ' +
								'src="http:\/\/assets.tumblr.com\/assets\/html\/like_iframe.html?_v=91caaea7b1611134ff834dad44299a8a#name=' + tumblr_api_read.tumblelog.name + '&amp;post_id=' + tumblr_api_read.posts[i].id + '&amp;rk=' + tumblr_api_read.posts[i]['reblog-key'] + '" ' +
                //'src="https:\/\/www.tumblr.com\/dashboard\/iframe?lang=en_US&amp;src=' + encodeURIComponent(tumblr_api_read.posts[i].url) + '&amp;pid=' + tumblr_api_read.posts[i].id + '&amp;rk=' + tumblr_api_read.posts[i]['reblog-key'] + '" ' +
								'scrolling="no" ' +
								'width="' + ((Morpheme.state.postId || !MyExtension.config.inline) ? '21' : '16') + '" ' +
								'height="' + ((Morpheme.state.postId || !MyExtension.config.inline) ? '21' : '16') + '" ' +
								'frameborder="0" ' +
								'class="like_toggle" ' +
								'allowTransparency="true"><\/iframe>' +
						'<\/span>' +
						((navigator.appName === 'Microsoft Internet Explorer')
							? (
								'<!--[if IE]><script type="text\/javascript">' +
									'document.getElementById("like_iframe_' + tumblr_api_read.posts[i].id + '").allowTransparency=true;' +
								'<\/script><![endif]-->'
							)
							: ''
						) +
						'&nbsp;&nbsp;' +
						'<a ' + 
							'id="reblogMorpheme" ' +
							'title="[R] - Reblog" ' +
							'href="http:\/\/www.tumblr.com\/reblog\/' + tumblr_api_read.posts[i].id + '\/' + tumblr_api_read.posts[i]['reblog-key'] + '?redirect_to=' + encodeURIComponent(tumblr_api_read.posts[i].url) + '" ' +
							'target="_blank" ' +
							'class="reblog_button" ' +
							'style="width: ' + 
								((Morpheme.state.postId || !MyExtension.config.inline) ? '21' : '16') + 'px; height: ' + 
								((Morpheme.state.postId || !MyExtension.config.inline) ? '21' : '16') + 'px;"' + //display: block;
							'><svg ' +
								'width="100%" height="100%" ' +
								'viewBox="0 0 537 512" ' +
								'xmlns="http://www.w3.org/2000/svg" ' +
								'xmlns:xlink="http://www.w3.org/1999/xlink" fill="#ccc"><path ' +
								'd="M 98.893,177.139c0.00-7.462, 4.826-12.275, 12.288-12.275L 405.12,164.864 l0.00,83.469 l 118.72-120.947L 405.12,8.678l0.00,81.51 L 49.382,90.189 c-15.206,0.00-27.648,12.429-27.648,27.648l0.00,171.814 l 77.146-71.603L 98.88,177.139 z M 438.874,332.646c0.00,7.45-4.826,12.275-12.275,12.275L 123.75,344.922 l0.00-83.469 l-116.506,120.922l 116.506,120.947l0.00-81.498 l 356.864,0.00 c 15.206,0.00, 27.648-12.454, 27.648-27.648L 508.262,220.134 l-69.402,71.59L 438.861,332.646 z" ></path></svg><\/a>' +
						'&nbsp;&nbsp;' +
						'</span>'
	)
) + 
						'<table id="tableLikesMorpheme' + tumblr_api_read.posts[i].id + '" border="0" cellspacing="0" cellpadding="0" style="visibility: hidden; display: none;"><tr>' + 

(MyExtension.config.debug
	? (
		'<td><div id="googleplus_controls' + tumblr_api_read.posts[i].id + '"><div class="g-plusone" data-size="medium" data-count="true" data-width="120px" data-annotation="none" data-href="' + tumblr_api_read.posts[i].url + '"><\/div><\/div><\/td>' +
		'<td>&nbsp;<\/td>' +
		'<td>' +
			'<iframe id="facebook_controls' + tumblr_api_read.posts[i].id + '" src="" allowtransparency="true" ' +
			'style="border: medium none; overflow: hidden; width: 120px; height: 21px;" frameborder="0" scrolling="no"><\/iframe>' +
		'<\/td>' +
		'<td>&nbsp;<\/td>'
	)
	: ''
) +

						'<td colspan="4"><iframe ' +
							'id="tumblr_controls' + tumblr_api_read.posts[i].id + '" ' +
							'src="' + (
								(navigator.appName === 'Microsoft Internet Explorer')
									? 'about:Tabs'
									: ''
							) + '" ' +
							'scrolling="no" frameborder="0" ' +
							'style="OLDWIDTH: 240px; width: 260px; height: 29px; top:0px; right:0px; border:0px; background-color:transparent;">' +
						'<\/iframe>' +
						((navigator.appName === 'Microsoft Internet Explorer')
							? (
								'<!--[if IE]><script type="text\/javascript">' +
									'document.getElementById("tumblr_controls' + tumblr_api_read.posts[i].id + '").allowTransparency=true;' +
								'<\/script><![endif]-->'
							)
							: ''
						)+
						'<\/td>' +
						'<\/tr><\/table>';

					//var htmlBodyCode = '';
					//var htmlCaptionCode = '';

					htmlCode += 
						'<span ' +
							'id="spanPostMorpheme' + tumblr_api_read.posts[i].id + '" ' +
							'onclick="javascript:MyExtension.utils.moveCursorPosition(this.id); return true;"' +
							'class="' + MyExtension.utils.buildPostClass() + '">' +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((htmlHeadCode !== '')
								? ('<span class="headPostMorpheme">' + htmlHeadCode + '<\/span>')
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							(MyExtension.config.debug
								? (
									'<br \/>' +
									'Type: <b>' + tumblr_api_read.posts[i].type + '<\/b>;<br \/>' +
									'No.: ' + (((Morpheme.state.currentPage - 1) * Morpheme.config.postsPerLoad) + i + 1) + ';<br \/>' +
									'Id: ' + tumblr_api_read.posts[i].id + ';<br \/>'
								)
								: ''
							) +
'<br \/>' +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'photo')
								? (
									'<input id="photoHR' + tumblr_api_read.posts[i].id + '" type="hidden" value="' + tumblr_api_read.posts[i]['photo-url-1280'] + '" \/>' +
									'<input id="photoLR' + tumblr_api_read.posts[i].id + '" type="hidden" value="' + tumblr_api_read.posts[i]['photo-url-500'] + '" \/>' +
									'<span class="bodyPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
										'<a ' +

//(MyExtension.utils.isViewer()
//	?
	(
		'onclick="javascript:' +
			'MyExtension.utils.moveCursorPosition(\'spanPostMorpheme' + tumblr_api_read.posts[i].id + '\');' +
			'MyExtension.utils.fullScreen(true);' +
			'return false;" '
	) +
//	: ''
//) +

											(MyExtension.utils.isViewer() ? '' : 'target="_blank" ') +
											'href="' + (
												Morpheme.state.postId
													? tumblr_api_read.posts[i]['photo-url-1280']
													: MyExtension.utils.urlConvertToInternal(tumblr_api_read.posts[i].url)
											) + '">' +
											'<img ' +
												'id="image' + tumblr_api_read.posts[i].id + '" ' +
												'src="' + tumblr_api_read.posts[i]['photo-url-' + MyExtension.state.photoRes] + '" \/>' +
										'<\/a>' +
										htmlPhotosCode +
									'<\/span>' +
									((tumblr_api_read.posts[i]['photo-caption'] === '')
										? ''
										: (
											'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
												(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['photo-caption']) : tumblr_api_read.posts[i]['photo-caption']) +
											'<\/span>'
										)
									)
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'regular')
								? (
									'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
										(tumblr_api_read.posts[i]['regular-title']
											? (
												(MyExtension.config.blockScripts
													? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['regular-title'])
													: tumblr_api_read.posts[i]['regular-title']
												) +
												'<br \/>'
											)
											: ''
										) +
										(MyExtension.config.blockScripts
											? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['regular-body'])
											: tumblr_api_read.posts[i]['regular-body']
										) +
									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'quote')
								? (
									'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
										(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['quote-text']) : tumblr_api_read.posts[i]['quote-text']) +
										(tumblr_api_read.posts[i]['quote-source']
											? (
												'<br \/><br \/>' + 
												(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['quote-source']) : tumblr_api_read.posts[i]['quote-source'])
											)
											: ''
										) +
										'<br \/><br \/>' +
									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'video')
								? (
									'<span class="bodyPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
									(((tumblr_api_read.posts[i]['video-player'] == null) || (tumblr_api_read.posts[i]['video-player'] == false)) ? '' : (MyExtension.config.showPlayers 
										? tumblr_api_read.posts[i]['video-player']
										: (
											'<script type="text\/javascript">' +
											'var player' + tumblr_api_read.posts[i].id + '=\'' +
												tumblr_api_read.posts[i]['video-player'].replace(/'/gi, '\\\'').replace(/\//gi, '\\\/') +
											'\';' +
											'<\/script>' +
											'<span class="buttonMorpheme smallMorpheme" ' +
												'onclick="javascript:this.innerHTML=player' + tumblr_api_read.posts[i].id + ';">show video player<\/span>'
										)
									)) +
									'<\/span>' +
									'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
										(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['video-caption']) : tumblr_api_read.posts[i]['video-caption']) +
									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'audio')
								? (
									'<span class="bodyPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
									(MyExtension.config.showPlayers 
										? tumblr_api_read.posts[i]['audio-player']
										: (
											"<script type='text\/javascript'>" +
											"var player" + tumblr_api_read.posts[i].id + "='" +
												tumblr_api_read.posts[i]['audio-player'].replace(/'/gi, "\\'").replace(/\//gi, "\\\/") +
											"';" +
											'<\/script>' +
											'<span class="buttonMorpheme smallMorpheme" ' +
												'onclick="javascript:this.innerHTML=player' + tumblr_api_read.posts[i].id + ';">show audio player<\/span>'
										)
									) + 
									'<\/span>' +
									'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
									(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['audio-caption']) : tumblr_api_read.posts[i]['audio-caption']) +
									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'link')
								? (
									'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +

										'[&nbsp;<a target="_blank" href="' + tumblr_api_read.posts[i]['link-url'] + '">' +
											(tumblr_api_read.posts[i]['link-text'] 
												? (MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['link-text']) : tumblr_api_read.posts[i]['link-text'])
												: 'LINK'
											) +
										'<\/a>&nbsp;]' +
										((
											tumblr_api_read.posts[i]['link-text'] &&
											tumblr_api_read.posts[i]['link-description']
										) 
											? '<br \/>'
											: ''
										) +
										(tumblr_api_read.posts[i]['link-description']
											? (MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['link-description']) : tumblr_api_read.posts[i]['link-description'])
											: ''
										) +

									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'answer')
								? (
									'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +

										(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i].question) : tumblr_api_read.posts[i].question) +
										(tumblr_api_read.posts[i].answer
											? (
												'<br \/>' +
												(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i].answer) : tumblr_api_read.posts[i].answer)
											)
											: ''
										) +

									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((tumblr_api_read.posts[i].type === 'conversation')
								? (
									'<span class="captionPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +

										(tumblr_api_read.posts[i]['conversation-title']
											? (
												(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['conversation-title']) : tumblr_api_read.posts[i]['conversation-title']) +
												'<br \/><br \/>'
											)
											: ''
										) +

										//(MyExtension.config.blockScripts ? Morpheme.utils.stripper.stripScripts(tumblr_api_read.posts[i]['conversation-text']) : tumblr_api_read.posts[i]['conversation-text']) +
										htmlConversationCode +

									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							((htmlTagsCode !== '')
								? (
									'<span class="tagsPostMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme">' +
										htmlTagsCode +
									'<\/span>'
								)
								: ''
							) +
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
							///////////////////////////////////////////////////////////////////////////////////////////////////////////
						'<\/span>' +
						MyExtension.utils.conditionalBreakLine(MyExtension.state.postCount)
					;

					MyExtension.state.postCount++;
				}
				htmlCode += '<\/span>';
				$('#' + MyExtension.config.postDumper).append(htmlCode);

				if (!(typeof Tumblr === 'undefined')) {
					var ids = new Array();
					for (var i = 0; i < tumblr_api_read.posts.length; i++) {
						ids[i] = tumblr_api_read.posts[i].id;
					}
					Tumblr.LikeButton.get_status_by_post_ids(ids);
				}

				if (!finished) {
					MyExtension.utils.button.setButtonState(true, false, false, true);

					// keep loading until screen is full of posts
					if ($(document).height() == $(window).height()) {

// carefull with this
Morpheme.state.isRunning = false;

						if (Morpheme.loadPosts()) { MyExtension.utils.button.setButtonState(false, false, false, true); }
					}
				}

				MyExtension.state.isRunning = false;
			},
			noMorePosts: function() {
				'use strict';

				if (Morpheme.state.postId) {
					MyExtension.utils.button.setButtonState(false, true, false, false);
				} else {
					MyExtension.utils.button.setButtonState(false, true, false, true);
				}
			}, 
			postsError: function(error) {
				'use strict';

				MyExtension.utils.button.setButtonState(true, false, true, true);
			}
		}
	},
	state: {
		fullscreen: false,
		fullscreenEvent: null,
		fullscreenCursorPositionId: null,
		fullScreenMessagesEvent: null,
		photoRes: 250,
		photosRes: 75,

		postCount: 1,
		cursorPosition: null,
		isRunning: false,
		isKeyboardRunning: false,



postsPerLine: Math.floor((window.innerWidth -100) / 260) // -100 for margin and safety (from other elements, table margins, scroll, etc.)



	},
	utils: {
		conditionalBreakLine: function(count) {
			'use strict';

			if (!MyExtension.config.inline) { return ''; }

			return (((count % MyExtension.state.postsPerLine) !== 0) ? '' : '<br \/>');
		},
		button: {
			LOAD_POSTS: 'Load more posts',
			LOAD_AGAIN: 'Error loading posts, Click to Reload',
			LOADING: 'Loading...',
			FINISHED: 'finished! no more posts',

			button__: null,

			setButtonState: function(enabled, finished, error, visible) {
				'use strict';

				if (!this.button__) {
					this.button__ = document.getElementById(MyExtension.config.loadButton);
				}

				if (visible) {
					this.button__.style.visibility = 'visible';
					this.button__.style.display = 'inline-block';
				} else {
					this.button__.style.visibility = 'hidden';
					this.button__.style.display = 'none';
				}
				this.button__.disabled = !enabled;
				this.button__.value = (enabled ? (error ? this.LOAD_AGAIN : this.LOAD_POSTS) : (finished ? this.FINISHED : this.LOADING));
			},
			
			hide: function() {
				'use strict';

				if (!this.button__) {
					this.button__ = document.getElementById(MyExtension.config.loadButton);
				}

				this.button__.style.visibility = 'hidden';
				this.button__.style.display = 'none';
			}
		},

		buildPostClass: function() {
			'use strict';

			return 'postMorpheme ' + (MyExtension.config.inline ? 'inline' : 'block') + 'Morpheme';
		},
		isviewer__: null,
		isViewer: function () {
			'use strict';

			if (!this.isviewer__) {
				this.isviewer__ = !!Morpheme.utils.url.getParam.byName('url');
			}
			return this.isviewer__;
		}, 
		buildQuery: function(inline, type, isviewer) {
			'use strict';

			var args = '';
			if (isviewer) { args += (args === '' ? '' : '&') + 'url=' + Morpheme.utils.url.getParam.byName('url'); }
			args += (args === '' ? '' : '&') + 'inline=' + (inline ? 'true' : 'false');
			if (type) { args += (args === '' ? '' : '&') + 'type=' + type; }

			return Morpheme.utils.windowLocationHrefNoParams() + ((args === '') ? '' : ('?' + args));
		},

		swapCursorPosition: function(fromSpan, toSpan) {
			'use strict';

			if (fromSpan) {
				//fromSpan.style.borderColor = null;
				fromSpan.setAttribute('class', this.buildPostClass());
			}

			if (toSpan) {
				//toSpan.style.borderColor = 'red';
				toSpan.setAttribute('class', this.buildPostClass() + ' postMorphemeCursor');
				
				//toSpan.getElementsByTagName('a')[0].focus();
			}
		},
		moveCursorPosition: function(spanId) {
			'use strict';

			// returns:
			//           0 if already there
			//           1 if moved
			//          -1 couldn't find destination to move to

			var span = document.getElementById(spanId);
			if (
				MyExtension.state.cursorPosition &&
				(MyExtension.state.cursorPosition == span)
			) {
				return 0;
			}
			if (!span) {
				return -1;
			}

			MyExtension.utils.swapCursorPosition(
				(MyExtension.state.cursorPosition ? MyExtension.state.cursorPosition : null),
				span
			);

			MyExtension.state.cursorPosition = span;

			return 1;
		},
		urlConvertToInternal: function (url) {
			'use strict';

			return (
				MyExtension.utils.isViewer() ?
					(
						Morpheme.utils.windowLocationHrefNoParams() +
						'?url=' +
						encodeURIComponent(url) +
						(MyExtension.config.inline ? '&inline=true' : '')
					)
					: url
			);
		},
		anchorOpen: function (anchorName, sameWindow, isInternal) {
			'use strict';

			if (MyExtension.state.cursorPosition) {
				for (
					var
						anchors = MyExtension.state.cursorPosition.getElementsByTagName('a'),
						i = 0;
					i < anchors.length;
					i++
				) {
					if (anchors[i].id === anchorName) {

						//if (sameWindow || isInternal) {
						if (sameWindow) {
							window.location = anchors[i].href;
						} else {
							window.open(anchors[i].href);
						}

						break;
					}
				}
			}
		},

		tumblr_controls__: null,
		tumblr_controls: function() {
			'use strict';

			if (!this.tumblr_controls__) {
				this.tumblr_controls__ = document.getElementById('tumblr_controls');
			}
			return this.tumblr_controls__;
		},
		tablepopup__: null,
		tablePopup: function() {
			'use strict';

			if (!this.tablepopup__) {
				this.tablepopup__ = document.getElementById(MyExtension.config.tablePopup);
			}

			return this.tablepopup__;
		},
		spanmessage__: null,
		spanMessage: function() {
			'use strict';

			if (!this.spanmessage__) {
				this.spanmessage__ = document.getElementById(MyExtension.config.spanMessage);
			}

			return this.spanmessage__;
		},
		divpopup__: null,
		divPopup: function() {
			'use strict';

			if (!this.divpopup__) {
				this.divpopup__ = document.getElementById(MyExtension.config.divPopup);
			}

			return this.divpopup__;
		},
		divshortcuts__: null,
		divShortcuts: function() {
			'use strict';

			if (!this.divshortcuts__) {
				this.divshortcuts__ = document.getElementById(MyExtension.config.divShortcuts);
			}

			return this.divshortcuts__;
		},
		spanprevious__: null,
		spanPrevious: function() {
			'use strict';

			if (!this.spanprevious__) {
				this.spanprevious__ = document.getElementById(MyExtension.config.spanPrevious);
			}

			return this.spanprevious__;
		},
		spannext__: null,
		spanNext: function() {
			'use strict';

			if (!this.spannext__) {
				this.spannext__ = document.getElementById(MyExtension.config.spanNext);
			}

			return this.spannext__;
		},
		spanexit__: null,
		spanExit: function() {
			'use strict';

			if (!this.spanexit__) {
				this.spanexit__ = document.getElementById(MyExtension.config.spanExit);
			}

			return this.spanexit__;
		},
		body__: null,
		body: function() {
			'use strict';

			if (!this.body__) {
				this.body__ = document.getElementById(MyExtension.config.body);
			}

			return this.body__;
		},

		cursor: function(isNext) {
			'use strict';

			if (
				MyExtension.state.cursorPosition ||
				isNext
			) {
				//if (
				//	(MyExtension.state.isRunning) ||
				//	(MyExtension.state.isKeyboardRunning)
				//) {
				//	// this never happens, just in case... more thread safe
				//	event.preventDefault();
				//	return;
				//}
				MyExtension.state.isKeyboardRunning = true;


				var
					spans = document.getElementsByTagName('span'),
					previousPosition = MyExtension.state.cursorPosition,
					isTopOrBottom = true,
					found = false;
				for (var i = (isNext) ? 0 : spans.length -1; (isNext) ? (i < spans.length) : (i >= 0); (isNext) ? (i++) : (i--)) {
					if (spans[i].id.indexOf('spanPostMorpheme') === 0) {

						if (!MyExtension.state.cursorPosition) {
							isTopOrBottom = false;
							MyExtension.state.cursorPosition = spans[i];
							break;

						} else if (MyExtension.state.cursorPosition == spans[i]) {
							found = true;
							continue;

						} else if (found) {
							isTopOrBottom = false;
							MyExtension.state.cursorPosition = spans[i];
							break;

						}
					}
				}

				if (isTopOrBottom) {
					if (isNext) {
						if (Morpheme.loadPosts()) { MyExtension.utils.button.setButtonState(false, false, false, true); }


						MyExtension.state.isKeyboardRunning = false;
						return;


					} else {
						$(window).scrollTop(0);

						MyExtension.state.cursorPosition = null;
					}
				} else {
					if (!MyExtension.state.fullscreen) {
						$(window).scrollTop($(MyExtension.state.cursorPosition).position().top);
					}
				}

				MyExtension.utils.swapCursorPosition(
					previousPosition ? previousPosition : null,
					MyExtension.state.cursorPosition ? MyExtension.state.cursorPosition : null
				);

				//if (MyExtension.state.cursorPosition) {
				//	MyExtension.state.cursorPosition.getElementsByTagName('a')[0].focus();
				//}

				if (MyExtension.state.fullscreen) {
					MyExtension.utils.fullScreenMessages(false);
					MyExtension.utils.popupImage(!!MyExtension.state.cursorPosition);
				}


				MyExtension.state.isKeyboardRunning = false;
			}
		},

		fullScreenMessages: function(show) {
			'use strict';

			if (MyExtension.state.fullScreenMessagesEvent) {
				clearTimeout(MyExtension.state.fullScreenMessagesEvent);
				MyExtension.state.fullScreenMessagesEvent = null;
			}

			var
				spanPrevious = MyExtension.utils.spanPrevious(),
				spanNext = MyExtension.utils.spanNext(),
				spanExit = MyExtension.utils.spanExit();

			if (show) {
				spanPrevious.style.visibility = 'visible';
				spanNext.style.visibility = 'visible';
				spanExit.style.visibility = 'visible';
				spanExit.style.display = 'block';
				
				MyExtension.state.fullScreenMessagesEvent = setTimeout(
					function() {
						MyExtension.utils.fullScreenMessages(false);
					}, 
					3000
				);
			} else {
				spanPrevious.style.visibility = 'hidden';
				spanNext.style.visibility = 'hidden';
				spanExit.style.visibility = 'hidden';
				spanExit.style.display = 'inline-block';
			}
		},

		fullScreen: function(show) {
			'use strict';

			if (MyExtension.state.fullscreenEvent) {
				clearTimeout(MyExtension.state.fullscreenEvent);
				MyExtension.state.fullscreenEvent = null;
			}

			if  (show) {
				if (!MyExtension.state.fullscreen && MyExtension.state.cursorPosition) {
					MyExtension.utils.tablePopup().style.background = null;

					MyExtension.utils.fullScreenMessages(true);

					if (MyExtension.utils.tumblr_controls()) {
						MyExtension.utils.tumblr_controls().style.visibility = 'hidden';
					}
					MyExtension.utils.divShortcuts().style.visibility = 'hidden';
					MyExtension.state.fullscreen = true;
					MyExtension.utils.body().style.overflow = 'hidden';

// ToDos: here! Must test this on touch screen devices:
//document.body.addEventListener('touchmove', function(e) { e.preventDefault(); });
//document.body.addEventListener('touchstart', function(e) { e.preventDefault(); }); 

					MyExtension.utils.popupImage(true);
				}
			} else {
				if (MyExtension.state.fullscreen) {

					if (MyExtension.utils.tumblr_controls()) {
						MyExtension.utils.tumblr_controls().style.visibility = 'visible';
					}
					MyExtension.utils.divShortcuts().style.visibility = 'visible';
					MyExtension.state.fullscreen = false;
					MyExtension.utils.body().style.overflow = 'auto';

					$(window).scrollTop($(MyExtension.state.cursorPosition).position().top);

// ToDos: here! Must test this on touch screen devices:
//document.body.removeEventListener('touchmove', function(e) { e.preventDefault(); });
//document.body.removeEventListener('touchstart', function(e) { e.preventDefault(); }); 

					MyExtension.utils.popupImage(false);
				}
			}
		},
		popupImage: function(show) {
			'use strict';

			if (MyExtension.state.fullscreenEvent) {
				clearTimeout(MyExtension.state.fullscreenEvent);
				MyExtension.state.fullscreenEvent = null;
			}

			if (show) {
				var
					inputs = MyExtension.state.cursorPosition.getElementsByTagName('input'),
					input = null,
					inputLR = null;
				for (var i = 0; i < inputs.length; i++) {
					if (inputs[i].id.indexOf('photoHR') === 0) {
						input = inputs[i];
					}
					if (inputs[i].id.indexOf('photoLR') === 0) {
						inputLR = inputs[i];
					}

					if (input && inputLR) {
						break;
					}
				}

				if (input && inputLR) {
					var
						tablePopup = MyExtension.utils.tablePopup(), // tablePopup.style.background = null;
						spanMessage = MyExtension.utils.spanMessage();
					spanMessage.style.visibility = 'visible';
					spanMessage.innerHTML = 'Loading high resolution photo...';

					tablePopup.style.background = 'url(' + inputLR.value + ') no-repeat center center fixed';
					tablePopup.style.backgroundSize = 'contain'; // '100% 100%';

					var
						cursorpositionid = MyExtension.state.cursorPosition.id,
						image = new Image();
					MyExtension.state.fullscreenEvent = Morpheme.utils.image.load(
						image,           // image,
						input.value,     // src,
						function() {     // successEvent,
							MyExtension.state.fullscreenEvent = null;

							if (cursorpositionid === MyExtension.state.cursorPosition.id) {
								tablePopup.style.background = 'url(' + image.src + ') no-repeat center center fixed';
								tablePopup.style.backgroundSize = 'contain'; // '100% 100%';

								spanMessage.style.visibility = 'hidden';
								spanMessage.innerHTML = '';
							}
						},
						10000,           // timeout,
						function() {     // timeoutEvent
							MyExtension.state.fullscreenEvent = null;

							if (cursorpositionid === MyExtension.state.cursorPosition.id) {
								//tablePopup.style.background = null;

								spanMessage.style.visibility = 'visible';
								spanMessage.innerHTML = 
									'Error loading high resolution photo, ' +
									'<a href="#" onclick="javascript:return false;">Click to Retry<\/a>';
								spanMessage.getElementsByTagName('a')[0].focus();
							}
						}
					);


					var divPopup = MyExtension.utils.divPopup();
					//divPopup.style.height = $(window).height() + 'px';
					divPopup.style.top = $(window).scrollTop() + 'px';
					divPopup.style.display = 'block';

					return true;
				} else {
					this.popupImage(false);
					return false;
				}

			} else {
				MyExtension.utils.divPopup().style.display = 'none';

// ToDos: here! better solution, endless recursion on the verge of happenning
if (MyExtension.state.fullscreen) {
	MyExtension.utils.fullScreen(false);
}

				return true;
			}
		}
	}
};